package edu.ccut.saturn.studio.logic.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.swt.graphics.Image;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import edu.ccut.saturn.studio.core.search.IObserver;
import edu.ccut.saturn.studio.core.search.SaturnFileSearcher.SearchResult;
import edu.ccut.saturn.studio.core.util.eclipse.SaturnProjectUtil;
import edu.ccut.saturn.studio.core.util.xml.SaturnW3CUtil;
import edu.ccut.saturn.studio.dialog.normal.SaturnNormalDialog;
import edu.ccut.saturn.studio.export.createhtml.Parameters;
import edu.ccut.saturn.studio.logic.model.saturn.ErrorInfo;
import edu.ccut.saturn.studio.logic.model.saturn.SaturnArg;
import edu.ccut.saturn.studio.logic.model.saturn.SaturnContent;
import edu.ccut.saturn.studio.logic.model.saturn.SaturnParameter;
import edu.ccut.saturn.studio.logic.model.saturn.SaturnTransformNode;
import edu.ccut.saturn.studio.logic.model.saturn.SaturnValidate;
import edu.ccut.saturn.studio.logic.model.saturn.SaturnWebContextNode;
import edu.ccut.saturn.studio.logic.model.saturn.SaturnWebContextParameter;
import edu.ccut.saturn.studio.util.ConversionUtil;
import edu.ccut.saturn.studio.util.IconFactory;

public abstract class Shape extends BasicShape implements IShapeSearcher {

	public static final String KEY_PARAMETER_ATTRIBUTE_VALIDATE_CUSTOM_JS_METHOD = "custom-js-method";

	public static final String KEY_PARAMETER_ATTRIBUTE_VALIDATE_JS_METHOD_NAME = "js-method-name";

	public static final String KEY_PARAMETER_ATTRIBUTE_VALIDATE_KEY = "key";

	public static final String KEY_PARAMETER_ATTRIBUTE_VALIDATE_ARG = "arg";

	public static final String KEY_PARAMETER_ATTRIBUTE_VALIDATE_ARGS = "args";

	public static final String KEY_PARAMETER_ATTRIBUTE_VALIDATE_CLASS = "class";

	public static final String KEY_PARAMETER_ATTRIBUTE_VALIDATE = "validate";

	public static final String KEY_PARAMETER_ATTRIBUTE_CLASS_IS_VALIDATE = "isValidate";

	public static final String KEY_PARAMETER_ATTRIBUTE_VALIDATES = "validates";

	public static final String PROPERTY_PARAMETERS = "property_parameters";

	public static final String KEY_NODE_TRANSFORM_CONTENT_VALUE_KEY = "content-value-key";

	public static final String KEY_NODE_TRANSFORM_TYPE = "type";

	public static final String KEY_NODE_TRANSFORM_ID = "id";

	public static final String KEY_NODE_TANSFORM_CONTENT = "content";

	public static final String KEY_NODE_TANSFORM_CONTENTS = "contents";

	public static final String CONTETN_LINTSTYLE_STYLE = "style";

	public static final String KEY_ATTRIBUTE_X = "x";

	public static final String KEY_ATTRIBUTE_Y = "y";

	public static final String KEY_CHANGS = "keyCHANGS";

	public static final String KEY_ATTRIBUTE_SHAPE_ID = KEY_NODE_TRANSFORM_ID;

	public static final String KEY_ATTRIBUTE_SHAPE_NEXT_ID = "next";

	public static final String KEY_ELEMENT_SHAPE_NEXT_ID = "description";
	
//	public static final String KEY_ELEMENT_SHAPE_LOAD_START = "loadstart";

	public static final String KEY_NODE_CONNECTION = "connection";

	public static final String KEY_CONNECTION_ATTRIBUTE_SOURCE = "source";

	public static final String KEY_CONNECTION_ATTRIBUTE_TARGET = "target";

	public static final String KEY_NODE_PARAMETERS = "parameters";

	public static final String KEY_NODE_CONTENTS = "contents";

	public static final String KEY_NODE_CONTEXTS = "value-moves";

	public static final String KEY_NODE_PARAMETER = "parameter";

	public static final String KEY_PARAMETER_NODE_VALUE_KEY = "value-key";

	public static final String KEY_PARAMETER_NODE_SCOPE = "scope";

	public static final String KEY_PARAMETER_NODE_DESCRIPTION = "description";

	public static final String KEY_PARAMETER_ATTRIBUTE_ID = KEY_NODE_TRANSFORM_ID;

	public static final String KEY_PARAMETER_ATTRIBUTE_NAME = "name";

	public static final String KEY_PARAMETER_ATTRIBUTE_CLASS_TYPE = "classType";

	public static final String KEY_PARAMETER_ATTRIBUTE_PASSING_TYPE = "passingType";

	public static final String LOCATION_PROP = "Shape.Location";

	public static final String SIZE_PROP = "Shape.Size";

	public static final String NAME_PROP = "Shape.Name";

	public static final String SOURCE_CONNECTIONS_PROP = "Shape.SourceConn";

	public static final String TARGET_CONNECTIONS_PROP = "Shape.TargetConn";

	public static final String CONSTANT_SRC = "src";

	public static final String CONSTANT_LIB = "lib";

	public static final String KEY_DEC = "dec";

	public static final String PROPERTERY_CHANGS = "changs";

	public static final String PROPERTERY_ISCHANGD = "ischanged";

	private String id; // shape unique id

	private String nextId = "";

	private String name = "";

	private String description = "";
	
	private String loadstart = "flase";

	private Point location = new Point(0, 0);

	private String key = "";

	private Dimension size = new Dimension(50, 70);

	private List<Connection> sourceConnections = new ArrayList<Connection>();

	private List<Connection> targetConnections = new ArrayList<Connection>();

	private List<SaturnParameter> parameters = new ArrayList<SaturnParameter>();

	private List<SaturnContent> contents = new ArrayList<SaturnContent>();

	private List<SaturnWebContextParameter> contexts = new ArrayList<SaturnWebContextParameter>();

	private Document document;

	private Node node;

	private boolean ischanged = false;


	public boolean isIschanged() {
		return ischanged;
	}

	public void setIschanged(boolean ischanged) {
		this.ischanged = ischanged;
		firePropertyChange(PROPERTERY_CHANGS, null, ischanged);
	}

	public Node getNode() {
		return node;
	}

	public void setNode(Node node) {
		this.node = node;
	}

	public void addConnection(Connection conn) {

		if (conn == null || conn.getSource() == conn.getTarget()) {
			throw new IllegalArgumentException();
		}

		if (conn.getSource() == this) {
			sourceConnections.add(conn);
			firePropertyChange(SOURCE_CONNECTIONS_PROP, null, conn);
		} else if (conn.getTarget() == this) {
			targetConnections.add(conn);
			firePropertyChange(TARGET_CONNECTIONS_PROP, null, conn);
		}
	}

	/**
	 * Return a pictogram (small icon) describing this model element. Children
	 * should override this method and return an appropriate Image.
	 * 
	 * @return a 16x16 Image or null
	 */
	public abstract Image getIcon();

	public Image getSmallIcon() {
		return getIcon();
	}

	/**
	 * Return the Location of this shape.
	 * 
	 * @return a non-null location instance
	 */
	public Point getLocation() {
		return location.getCopy();
	}

	/**
	 * Return the Size of this shape.
	 * 
	 * @return a non-null Dimension instance
	 */
	public Dimension getSize() {
		return size.getCopy();
	}

	public List<SaturnParameter> getParameters() {
		return parameters;
	}

	public void setParameters(List<SaturnParameter> parameters) {
		if (this.parameters.size() != parameters.size()) {
			this.parameters = parameters;
			firePropertyChange(PROPERTY_PARAMETERS, null, parameters);
			return;
		}
		for (SaturnParameter para : this.parameters) {
			for (SaturnParameter newPara : parameters) {
				if (!para.equals(newPara)) {
					this.parameters = parameters;
					firePropertyChange(PROPERTY_PARAMETERS, null, parameters);
				}
			}
		}
	}

	public List<SaturnContent> getContents() {
		return contents;
	}

	public void setContents(List<SaturnContent> contents) {
		if (this.contents.size() != contents.size()) {
			this.contents = contents;
			firePropertyChange(KEY_NODE_CONTENTS, null, contents);
			return;
		}
		for (SaturnContent content : this.contents) {
			for (SaturnContent newContent : contents) {
				if (!content.equals(newContent)) {
					this.contents = contents;
					firePropertyChange(KEY_NODE_CONTENTS, null, contents);
				}
			}
		}
	}

	public List<SaturnWebContextParameter> getContexts() {
		return contexts;
	}

	public void setContexts(List<SaturnWebContextParameter> contexts) {
		if (this.contexts.size() != contexts.size()) {
			this.contexts = contexts;
			firePropertyChange(KEY_NODE_CONTEXTS, null, contexts);
			return;
		}
		for (SaturnWebContextParameter context : this.contexts) {
			for (SaturnWebContextParameter newContext : contexts) {
				if (!context.equals(newContext)) {
					this.contexts = contexts;
					firePropertyChange(KEY_NODE_CONTEXTS, null, contexts);
				}
			}
		}
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		if (!this.description.equals(description)) {
			this.description = description;
			firePropertyChange(KEY_DEC, null, description);
		}
	}

	public List<Connection> getSourceConnections() {
		return new ArrayList<Connection>(sourceConnections);
	}

	public List<Connection> getTargetConnections() {
		return new ArrayList<Connection>(targetConnections);
	}

	/**
	 * Remove an incoming or outgoing connection from this shape.
	 * 
	 * @param conn
	 *            a non-null connection instance
	 * @throws IllegalArgumentException
	 *             if the parameter is null
	 */
	public void removeConnection(Connection conn) {
		if (conn == null) {
			throw new IllegalArgumentException();
		}
		if (conn.getSource() == this) {
			sourceConnections.remove(conn);
			firePropertyChange(SOURCE_CONNECTIONS_PROP, null, conn);
		} else if (conn.getTarget() == this) {
			targetConnections.remove(conn);
			firePropertyChange(TARGET_CONNECTIONS_PROP, null, conn);
		}
	}

	public void setLocation(Point newLocation) {
		if (newLocation == null) {
			throw new IllegalArgumentException();
		}
		location.setLocation(newLocation);
		firePropertyChange(LOCATION_PROP, null, location);
	}

	/**
	 * Set the Size of this shape. Will not modify the size if newSize is null.
	 * 
	 * @param newSize
	 *            a non-null Dimension instance or null
	 */
	public void setSize(Dimension newSize) {
		if (newSize != null) {
			size.setSize(newSize); // (new Dimension(50, 70));
			firePropertyChange(SIZE_PROP, null, size);
		}
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		if (!this.name.equals(name)) {
			this.name = name;
			firePropertyChange(NAME_PROP, null, name);
		}
	}

	public String getId() {
		return id;
	}

	public void setId(String shapeId) {
		this.id = shapeId;
	}

	public String getNextId() {
		return nextId;
	}

	public void setNextId(String nextId) {
		this.nextId = nextId;
	}

	public abstract IFigure getFigure();

	public abstract Node doRefresh();

	public final void refresh() {
		this.clear();
		Node node = this.doRefresh();
		this.createBaseInfo(node);
		this.setNode(node);
	}
	
	public void clear() {
		if (this.document != null) {
			Element root = this.document.getDocumentElement();
			root.removeChild(getNode());
		}
	}

	public String toString() {
		return this.name;
	}

	protected void createContents(Node node) {
		Node contentsNode = document.createElement(KEY_NODE_TANSFORM_CONTENTS);
		if (contents != null) {
			for (SaturnContent content : contents) {
				Node contentNode = this.createContentNode(document, content);
				contentsNode.appendChild(contentNode);
			}
		}
		node.appendChild(contentsNode);
	}

	private void createBaseInfo(Node node) {
		SaturnW3CUtil.createAttribute(node, KEY_ATTRIBUTE_SHAPE_ID, this.id);
		SaturnW3CUtil.createAttribute(node, Shape.KEY_ATTRIBUTE_SHAPE_NEXT_ID,
				this.nextId);
		SaturnW3CUtil.createAttribute(node, KEY_ATTRIBUTE_X, ""
				+ getLocation().x);
		SaturnW3CUtil.createAttribute(node, KEY_ATTRIBUTE_Y, ""
				+ getLocation().y);
		SaturnW3CUtil.createChildNode(node, KEY_ELEMENT_SHAPE_NEXT_ID,
				this.description);
	}

	public void createConnections() {
		Node root = this.getRoot();;
		List<Node> connectionNodes = SaturnW3CUtil.getChildrenByName(root, KEY_NODE_CONNECTION);
		
		if (connectionNodes != null) {
			for (Node connectionNode : connectionNodes) {
				String sourceId = SaturnW3CUtil.getNodeAttributeValue(connectionNode, KEY_CONNECTION_ATTRIBUTE_SOURCE);
				
				if (this.id.equals(sourceId)) {
					root.removeChild(connectionNode);
				}
			}
		}
		
		for (Connection connection : this.sourceConnections) {
			Node connectionNode = SaturnW3CUtil.createChildNode(root, KEY_NODE_CONNECTION, null);
			SaturnW3CUtil.createAttribute(connectionNode,
					KEY_CONNECTION_ATTRIBUTE_SOURCE, connection.getSource()
							.getId());

			SaturnW3CUtil.createAttribute(connectionNode,
					KEY_CONNECTION_ATTRIBUTE_TARGET, connection.getTarget()
							.getId());
			SaturnW3CUtil.createAttribute(connectionNode,
					CONTETN_LINTSTYLE_STYLE, "" + connection.getLineStyle());
			SaturnW3CUtil.createAttribute(connectionNode,
					KEY_PARAMETER_ATTRIBUTE_NAME, connection.getLineName());
		}
	}

	private Node createContentNode(Document document, SaturnContent saturnContent) {
		Node node = document.createElement(KEY_NODE_TANSFORM_CONTENT);
		SaturnW3CUtil.createAttribute(node, KEY_NODE_TRANSFORM_ID, saturnContent
				.getId());
		SaturnW3CUtil.createAttribute(node, KEY_NODE_TRANSFORM_TYPE,
				saturnContent.getType());
		SaturnW3CUtil.createChildNode(node,
				KEY_NODE_TRANSFORM_CONTENT_VALUE_KEY, saturnContent
						.getContentValueKey());
		return node;
	}

	protected void createParemeters(Node node) {
		Node parametersNode = SaturnW3CUtil.createChildNode(node,
				KEY_NODE_PARAMETERS, null);

		if (parameters != null) {
			ConversionUtil.scopeMap(parameters);
			for (SaturnParameter parameter : parameters) {
				Node parameterNode = this.createParameterNode(parameter);

				parametersNode.appendChild(parameterNode);
			}
		}
	}

	private Node createParameterNode(SaturnParameter saturnParameter) {
		Node node = document.createElement(KEY_NODE_PARAMETER);

		SaturnW3CUtil.createAttribute(node, KEY_PARAMETER_ATTRIBUTE_ID,
				saturnParameter.getId());
		SaturnW3CUtil.createAttribute(node, KEY_PARAMETER_ATTRIBUTE_NAME,
				saturnParameter.getName());
		SaturnW3CUtil.createAttribute(node, KEY_PARAMETER_ATTRIBUTE_CLASS_TYPE,
				saturnParameter.getClassType());
		SaturnW3CUtil.createAttribute(node,
				KEY_PARAMETER_ATTRIBUTE_PASSING_TYPE, saturnParameter
						.getPassingType());

		SaturnW3CUtil.createChildNode(node, KEY_PARAMETER_NODE_VALUE_KEY,
				saturnParameter.getValueKey());
		SaturnW3CUtil.createChildNode(node, KEY_PARAMETER_NODE_SCOPE,
				saturnParameter.getScope());

		SaturnW3CUtil.createChildNode(node, KEY_PARAMETER_NODE_DESCRIPTION,
				saturnParameter.getDescription());

		if (saturnParameter.getValidates().size() > 0) {
			this.createValidates(node, saturnParameter);
		}

		return node;
	}

	private void createValidates(Node parameterNode,
			SaturnParameter saturnParameter) {

		Node node = SaturnW3CUtil.createChildNode(parameterNode,
				KEY_PARAMETER_ATTRIBUTE_VALIDATES, null);

		SaturnW3CUtil.createAttribute(node, KEY_PARAMETER_NODE_VALUE_KEY,
				saturnParameter.getValueKey());
		SaturnW3CUtil.createAttribute(node, KEY_PARAMETER_ATTRIBUTE_CLASS_TYPE,
				saturnParameter.getClassType());
		SaturnW3CUtil.createAttribute(node,
				KEY_PARAMETER_ATTRIBUTE_CLASS_IS_VALIDATE, saturnParameter
						.getIsValidate());

		for (SaturnValidate saturnValidate : saturnParameter.getValidates()) {
			Node validatNode = this.createValidate(saturnValidate);
			node.appendChild(validatNode);
		}
	}

	private Node createValidate(SaturnValidate saturnValidate) {
		Node node = document.createElement(KEY_PARAMETER_ATTRIBUTE_VALIDATE);
		SaturnW3CUtil.createChildNode(node,
				KEY_PARAMETER_ATTRIBUTE_VALIDATE_KEY, saturnValidate.getKey());
		SaturnW3CUtil.createChildNode(node, KEY_PARAMETER_ATTRIBUTE_NAME,
				saturnValidate.getName());
		SaturnW3CUtil.createChildNode(node,
				KEY_PARAMETER_ATTRIBUTE_VALIDATE_CLASS, saturnValidate
						.getValidateClass());
		SaturnW3CUtil.createChildNode(node, KEY_PARAMETER_NODE_DESCRIPTION,
				saturnValidate.getDescription());
		SaturnW3CUtil.createChildNode(node,
				KEY_PARAMETER_ATTRIBUTE_VALIDATE_JS_METHOD_NAME, saturnValidate
						.getJsMethodName());
		SaturnW3CUtil.createChildNode(node,
				KEY_PARAMETER_ATTRIBUTE_VALIDATE_CUSTOM_JS_METHOD,
				saturnValidate.getCustomJsMethod());
		SaturnW3CUtil.createChildNode(node, "validateType", saturnValidate
				.getValidateType());

		this.createArgs(node, saturnValidate);
		createEventInfo(node, saturnValidate);
		createErrInfo(node, saturnValidate);

		return node;
	}

	private void createEventInfo(Node validateNode, SaturnValidate saturnValidate) {
		Node node = SaturnW3CUtil.createChildNode(validateNode, "eventInfos",
				null);
		for (String evnet : saturnValidate.getEventInfos()) {
			SaturnW3CUtil.createChildNode(node, "eventInfo", evnet);
		}
	}

	private void createErrInfo(Node validateNode, SaturnValidate saturnValidate) {
		Node node = SaturnW3CUtil.createChildNode(validateNode, "errorInfos",
				null);
		for (ErrorInfo evnet : saturnValidate.getErrorInfos()) {
			Node arg = SaturnW3CUtil.createChildNode(node, "errorInfo", evnet
					.getValue());
			
			SaturnW3CUtil.createChildNode(arg, "key", evnet.getKey());
		}
	}

	protected void createArgs(Node validateNode, SaturnValidate saturnValidate) {

		Node node = SaturnW3CUtil.createChildNode(validateNode,
				KEY_PARAMETER_ATTRIBUTE_VALIDATE_ARGS, null);

		for (SaturnArg saturnArg : saturnValidate.getArgs()) {
			SaturnW3CUtil.createChildNode(node,
					KEY_PARAMETER_ATTRIBUTE_VALIDATE_ARG, saturnArg.getArg());
		}
	}

	public Dialog getDialog() {
		return new SaturnNormalDialog(super.getShell(), this);
	}

	public void reorder(Shape shape) {
		List<SaturnParameter> parameters = shape.getParameters();

		if (parameters != null) {
			Collections.sort(parameters);
			for (int i = 0; i < parameters.size(); i++) {
				shape.getParameters().get(i).setId("" + (i + 1));
			}
		}
	}

	public Document getDocument() {
		return document;
	}

	public Node getRoot() {
		return document.getDocumentElement();
	}

	public void setDocument(Document document) {
		this.document = document;
	}

	public String[] getContentValueKeys() {
		Set<String> valueList = new HashSet<String>();
		List<Shape> childshapes = getAllShapes();
		for (int i = 0; i < childshapes.size(); i++) {
			if (!(childshapes.get(i) instanceof SaturnTransformNode)) {
				for (int j = 0; j < childshapes.get(i).getParameters().size(); j++) {
					SaturnParameter saturnParameter = childshapes.get(i)
							.getParameters().get(j);
					if (!saturnParameter.getValueKey().equals("")) {
						valueList.add(saturnParameter.getValueKey());
					}
				}
			}
		}

		return valueList.toArray(new String[valueList.size()]);
	}

	public List<Shape> getAllShapes() {
		ShapesDiagram sd = (ShapesDiagram) this.getParent();
		List<Shape> childshapes = sd.getShapes();

		return childshapes;
	}

	public String[] getParameterValueKeys() {
		Set<String> valueList = new HashSet<String>();
		List<Shape> childshapes = getAllShapes();
		for (int i = 0; i < childshapes.size(); i++) {
			List<SaturnParameter> parameters = childshapes.get(i)
					.getParameters();
			for (int j = 0; j < parameters.size(); j++) {
				SaturnParameter parameter = parameters.get(j);
				if (!parameter.getValueKey().equals("")) {
					valueList.add(parameter.getValueKey());
				}
			}
		}
		return valueList.toArray(new String[valueList.size()]);
	}

	public String[] getValueKeyByScope(String scope) {
		Set<String> valueKeyList = new HashSet<String>();
		ShapesDiagram sd = (ShapesDiagram) this.getParent();
		List<Shape> shapes = sd.getShapes();
		for (Shape shape : shapes) {
			if (!(shape instanceof SaturnTransformNode || shape instanceof SaturnWebContextNode)) {
				List<SaturnParameter> parameters = shape.getParameters();
				if (parameters != null) {
					for (SaturnParameter parameter : parameters) {
						if (scope.equals(parameter.getScope())) {
							valueKeyList.add(parameter.getValueKey());
						}
					}
				}
			}
		}
		String[] ss = new String[valueKeyList.size()];
		ss = valueKeyList.toArray(ss);
		return ss;
	}

	public String getClassType(String valueKey) {
		ShapesDiagram sd = (ShapesDiagram) this.getParent();
		List<Shape> shapes = sd.getShapes();
		for (Shape shape : shapes) {
			List<SaturnParameter> parameters = shape.getParameters();
			if (parameters != null) {
				for (SaturnParameter parameter : parameters) {
					if (valueKey.equals(parameter.getValueKey())) {
						return parameter.getClassType();
					}
				}
			}
		}
		return "";
	}

	public String getPassingType(String valueKey) {
		ShapesDiagram sd = (ShapesDiagram) this.getParent();
		List<Shape> shapes = sd.getShapes();
		for (Shape shape : shapes) {
			List<SaturnParameter> parameters = shape.getParameters();
			if (parameters != null) {
				for (SaturnParameter parameter : parameters) {
					if (valueKey.equals(parameter.getValueKey())) {
						return parameter.getPassingType();
					}
				}
			}
		}
		return "";
	}
	public String getName(String valueKey) {
		ShapesDiagram sd = (ShapesDiagram) this.getParent();
		List<Shape> shapes = sd.getShapes();
		for (Shape shape : shapes) {
			List<SaturnParameter> parameters = shape.getParameters();
			if (parameters != null) {
				for (SaturnParameter parameter : parameters) {
					if (valueKey.equals(parameter.getValueKey())) {
						return parameter.getName();
					}
				}
			}
		}
		return "";
	}
	public String getDescription(String valueKey) {
		ShapesDiagram sd = (ShapesDiagram) this.getParent();
		List<Shape> shapes = sd.getShapes();
		for (Shape shape : shapes) {
			List<SaturnParameter> parameters = shape.getParameters();
			if (parameters != null) {
				for (SaturnParameter parameter : parameters) {
					if (valueKey.equals(parameter.getValueKey())) {
						return parameter.getDescription();
					}
				}
			}
		}
		return "";
	}

	public int getNumber(String expect, String[] classtype) {
		if (expect != null) {
			for (int i = 0; i < classtype.length; i++) {
				if (classtype[i].equals(expect)) {
					return i;
				}
			}
		}
		return -1;
	}

	public IProject findTheProject() {
		return SaturnProjectUtil.getProject(((ShapesDiagram) this.getParent())
				.getEditor().getEditorInput());
	}

	public Shape createSubstituteShape(Shape shape) {
		Shape shape2 = (Shape) shape.cloneShape(shape.getLocation(), shape);
		shape2.setImage(IconFactory.getImage(shape));
		return shape2;
	};

	protected abstract void setImage(Image image);

	public abstract Shape cloneShape(Point mousePoint, Shape shape);

	public void modifyShape() {
		((ShapesDiagram) this.getParent()).modifyShape(this);
	}

	public List<SaturnParameter> getListParameter(Document document) {
		return null;
	}

	public List<SearchResult> keyMapInWorkspace(IObserver observer) {
		return null;
	}

	public List<SearchResult> keyMapInProject(IObserver observer) {
		return null;
	}

	public Map<String, Document> keyMapInWorkspace() {
		return null;
	}

	public Map<String, Document> keyMapInProject() {
		return null;
	}

	public String getKey() {
		return key;
	}

	public void setKey(String key) {
		if (!this.key.equals(key)) {
			this.key = key;
			firePropertyChange(KEY_CHANGS, null, key);
		}
	}

	public void accept(IVisit v) {
		v.visit(this);
	}

	public void setSelection(String loadstart) {
		if (!this.loadstart.equals(loadstart)) {
			this.loadstart = loadstart;
			firePropertyChange(KEY_DEC, null, loadstart);
		}
	}

	public String getSelection() {
		return loadstart;
	}
	
	/**
	 * 生成项目开发文档中构件中节点的hmtl文档
	 * 
	 * @param filePath
	 * 				 生成文档的保存路径
	 * @param filePath
	 * 				 工程名信息等
	 * @return Parameters
	 *  			 返回节点链接信息对象
	 * */
	public abstract Parameters createNodeHtml(String filePath, String[] tempnames);
	
	
}